using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using RPGOnline.Controls.Map.Events;
using RPGOnline.Controls.Map.Layers;
using RPGOnline.Controls.Map.Layers.Lighting;
using RPGOnline.Controls.Map.Windows;
using RPGOnline.Properties;

namespace RPGOnline.Controls.Map
{
    public class MapControlPresenter
    {
        private readonly MapControl m_mapControl;
        private Map m_map;
        private TilesetPainter m_tilesetPainter;
        private readonly MapPropertiesForm m_mapPropertiesForm;

        public MapControlPresenter(MapControl mapControl, TilesetPainter tilesetPainter, MapPropertiesForm mapPropertiesForm)
        {
            m_mapControl = mapControl;
            m_mapControl.SetPresenter(this);
            m_tilesetPainter = tilesetPainter;
            m_mapPropertiesForm = mapPropertiesForm;
        }

        public void CreateNewMap()
        {
            CreateNewMapForm createNewMapForm = new CreateNewMapForm();
            if (createNewMapForm.ShowDialog(m_mapControl) != DialogResult.OK)
                return;

            MapTileset mapTileset = new MapTileset(m_mapControl.Device, Resources.Dungeon, new Size(32, 32));
            //mapTileset.Compose(new MapTileset(m_mapControl.Device, Resources.Ground02, new Size(32, 32)));
            //mapTileset.Compose(new MapTileset(m_mapControl.Device, Resources.Water, new Size(32, 32), 4));

            m_map = new Map(m_mapControl.Device, createNewMapForm.TileSize, createNewMapForm.MapSize);
            m_map.TileSets.Add(mapTileset);

            m_mapControl.SetCurrentMap(m_map);
            m_mapPropertiesForm.Object = m_map;
            m_tilesetPainter.TileSet = mapTileset;
        }

        public void SetCurrentLayer(MapLayer mapLayer)
        {
            m_map.CurrentLayer = mapLayer;
        }

        public void CreateNewLayer(string @new)
        {
            MapLayer mapLayer = m_map.NewLayer(@new);
            m_mapControl.SetCurrentLayer(mapLayer);
        }

        public void OnAreaPaint()
        {
            m_mapControl.OnCellMouseDown -= OnAddWallMouseDown;
            m_mapControl.OnCellMouseDown -= OnAddLightMouseDown;
            m_mapControl.OnCellMouseDown -= OnRemoveWallMouseDown;
            m_map.LightingLayer.ShowObstructions(false);
            m_map.LightingLayer.ShowLights(false);

            m_tilesetPainter.EnableAreaPaint();
        }

        public void EnablePaint()
        {
            m_mapControl.OnCellMouseDown -= OnAddWallMouseDown;
            m_mapControl.OnCellMouseDown -= OnAddLightMouseDown;
            m_mapControl.OnCellMouseDown -= OnRemoveWallMouseDown;
            m_map.LightingLayer.ShowObstructions(false);
            m_map.LightingLayer.ShowLights(false);

            m_tilesetPainter.TileSet = m_map.TileSets[0];
            m_tilesetPainter.EnablePaint();
        }

        public void OnAddLight()
        {
        	m_tilesetPainter.Disable();
            m_mapControl.OnCellMouseDown -= OnAddWallMouseDown;
            m_mapControl.OnCellMouseDown += OnAddLightMouseDown;   
        }

        private void OnAddLightMouseDown(object sender, CellEventArgs e)
        {
            m_map.AddLight(Color.White, new Vector2(e.Mouse.Location.X, e.Mouse.Location.Y), 100);
        }

        public void OnAddWall()
        {
			m_tilesetPainter.Disable();
            m_mapControl.OnCellMouseDown -= OnAddLightMouseDown;
            m_mapControl.OnCellMouseDown += OnAddWallMouseDown;
            m_mapControl.OnCellMouseDown -= OnRemoveWallMouseDown;
        }

        private void OnAddWallMouseDown(object sender, CellEventArgs e)
        {
            m_map.ObstructionLayer.SetObstruction(e.MapCell.X, e.MapCell.Y);
        }

        public void ShowLights(bool enabled)
        {
            m_map.LightingLayer.ShowLights(enabled);
        }

        public void ShowWalls(bool enabled)
        {
            m_map.LightingLayer.ShowObstructions(enabled);
        }

    	public void ShowGrid(bool enabled)
    	{
    		m_mapControl.GridVisible = enabled;
    	}

        public void OnRemoveWall()
        {
            m_mapControl.OnCellMouseDown -= OnAddLightMouseDown;
            m_mapControl.OnCellMouseDown -= OnAddWallMouseDown;
            m_mapControl.OnCellMouseDown += OnRemoveWallMouseDown;
        }

        private void OnRemoveWallMouseDown(object sender, CellEventArgs e)
        {
            m_map.ObstructionLayer.RemoveObstruction(e.MapCell.X, e.MapCell.Y);
        }
    }
}